package com.maxlen.camunda.controller;

import com.maxlen.camunda.constant.CamundaConstant;
import com.maxlen.camunda.entity.BpmnEntity;
import com.maxlen.camunda.entity.CamundaFormEntity;
import com.maxlen.camunda.entity.FormEntity;
import com.maxlen.camunda.entity.dto.*;
import com.maxlen.camunda.entity.vo.*;
import com.maxlen.camunda.exception.CamundaException;
import com.maxlen.camunda.service.BpmnService;
import com.maxlen.camunda.service.CamundaService;
import com.tcloudit.common.core.constant.UserConstants;
import com.tcloudit.common.core.web.domain.AjaxResult;
import com.tcloudit.common.core.web.domain.PageEntity;
import com.tcloudit.common.core.web.page.TableDataInfo;
import com.tcloudit.system.api.domain.CamundaUserPost.SelectUserVO;
import org.aspectj.weaver.loadtime.Aj;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.model.bpmn.impl.instance.camunda.CamundaFormDataImpl;
import org.camunda.bpm.model.bpmn.instance.camunda.CamundaFormData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/camunda")
public class CamundaController {

    @Autowired
    private CamundaService camundaService;

    /**
     * 根据Key获取所有版本的流程定义列表
     * @param page 分页搜索参数CamundaException
     * @return 结果
     */
    @GetMapping("/getProcessDefinition")
    public AjaxResult getProcessDefinition(@Validated PageEntity<String> page){
        TableDataInfo tableDataInfo = camundaService.getProcessDefinition(page);
        return AjaxResult.success(tableDataInfo);
    }

    /**
     * 根据部署ID删除流程定义
     * @param deploymentId 流程定义ID
     * @return 结果
     */
    @GetMapping("/removeProcessDefinitionByDeploymentId/{deploymentId}")
    public AjaxResult removeProcessDefinitionByDeploymentId(@PathVariable String[] deploymentId){
        int rows = camundaService.removeProcessDefinitionByDeploymentId(deploymentId);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 获取对应部署ID的BPMN模型
     * @param deploymentId 部署ID
     * @return 结果
     */
    @GetMapping("/getProcessBpmn/{deploymentId}")
    public AjaxResult getProcessBpmn(@PathVariable String deploymentId){
        String bpmn = camundaService.getProcessBpmn(deploymentId);
        return AjaxResult.success("", bpmn);
    }

    /**
     * 更新流程定义的状态
     * @param key 流程状态标识
     * @return 结果
     */
    @PutMapping("/updateProcessStatus/{key}")
    public AjaxResult updateProcessStatus(@PathVariable String key){
        int rows = camundaService.updateProcessStatus(key);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 发布工作流程
     * @param id bpmn表 id
     * @return 结果
     */
    @GetMapping("/createProcessDefinition/{id}" )
    public AjaxResult createProcessDefinition(@PathVariable String id){
        try {
            camundaService.createProcessDefinition(id);
        } catch (Throwable e) {
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.success();
    }

    /**
     * 获取流程定义监控列表
     * @param page 分页和检索
     * @return 结果
     */
    @PostMapping("/getProcessControl")
    public AjaxResult getProcessControl(@RequestBody PageEntity<ProcessControlKeyDTO> page){
        TableDataInfo tableDataInfo = camundaService.getProcessControl(page);
        return AjaxResult.success(tableDataInfo);
    }

    /**
     * 删除流程定义监控
     * @param processInstanceIds 流程定义ID集合
     * @return 结果
     */
    @DeleteMapping("/deleteProcessControl/{processInstanceIds}")
    public AjaxResult deleteProcessControl(@PathVariable String[] processInstanceIds){
        int rows = camundaService.deleteProcessControl(processInstanceIds);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 获取流程的表单
     * @param processInstanceId 流程定义ID
     * @return 结果
     */
    @GetMapping("/getProcessForm/{processInstanceId}")
    public AjaxResult getProcessForm(@PathVariable String processInstanceId) {
        ProcessFormVO processFormVO = camundaService.getProcessForm(processInstanceId);
        return AjaxResult.success(processFormVO);
    }

    /**
     * 获取流程的审批意见
     * @param processInstanceId 流程定义ID
     * @return 结果
     */
    @GetMapping("/getProcessComment/{processInstanceId}")
    public AjaxResult getProcessComment(@PathVariable String processInstanceId) {
        List<ProcessCommentVO> processCommentVOs = camundaService.getProcessComment(processInstanceId);
        return AjaxResult.success(processCommentVOs);
    }

    /**
     * 获取需要展示的流程图
     * @param processInstanceId 流程定义ID
     * @return 结果
     */
    @GetMapping("/getProcessShowBpmn/{processInstanceId}")
    public AjaxResult getProcessShowBpmn(@PathVariable String processInstanceId) {
        ProcessBpmnVO processBpmnVO = camundaService.getProcessShowBpmn(processInstanceId);
        return AjaxResult.success(processBpmnVO);
    }

    /**
     * 获取当前部署流程的节点的权限
     * @param taskId 任务ID
     * @return 结果
     */
    @GetMapping("/getProcessAuth/{taskId}")
    public AjaxResult getProcessAuth(@PathVariable String taskId){
        List<String> authList = camundaService.getProcessAuth(taskId);
        return AjaxResult.success(authList);
    }

    /**
     * 完成任务
     * @param taskCompleteDTO 参数
     * @return R
     */
    @PostMapping("/completeTask")
    public AjaxResult completeTask(@RequestBody TaskCompleteDTO taskCompleteDTO){
        try{
            int rows = camundaService.completeTask(taskCompleteDTO);
            return rows > 0 ? AjaxResult.success() : AjaxResult.error();
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 加签
     * @param signDTO 加签请求参数
     * @return 结果
     */
    @PostMapping("/addSign")
    public AjaxResult addSign(@RequestBody SignDTO signDTO){
        int rows = camundaService.addSign(signDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 获取加签的选人列表
     * @param taskId 任务ID
     * @return 结果
     */
    @GetMapping("/selectAddSignUser/{taskId}")
    public AjaxResult selectAddSignUser(@PathVariable String taskId){
        try{
            List<SelectUserVO> selectUserVOList = camundaService.selectAddSignUser(taskId);
            return AjaxResult.success(selectUserVOList);
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }


    /**
     * 获取办理的选人列表
     * @param taskId 任务ID
     * @return 结果
     */
    @GetMapping("/selectCompleteUser/{taskId}")
    public AjaxResult selectCompleteUser(@PathVariable String taskId){
        try{
            SelectCompleteUserVO selectCompleteUser = camundaService.selectCompleteUser(taskId);
            return AjaxResult.success(selectCompleteUser);
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 获取减签的选人列表
     * @param taskId 任务ID
     * @return 结果
     */
    @GetMapping("/selectDeleteSignUser/{taskId}")
    public AjaxResult selectDeleteSignUser(@PathVariable String taskId){
        try{
            List<SelectUserVO> selectUserVOList = camundaService.selectDeleteSignUser(taskId);
            return AjaxResult.success(selectUserVOList);
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 减签
     * @param signDTO 参数
     * @return 结果
     */
    @PostMapping("/deleteSign")
    public AjaxResult deleteSign(@RequestBody SignDTO signDTO){
        int rows = camundaService.deleteSign(signDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 委托
     * @param delegateDTO 参数
     * @return 结果
     */
    @PostMapping("/delegate")
    public AjaxResult delegate(@RequestBody DelegateDTO delegateDTO){
        int rows = camundaService.delegate(delegateDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 解决委托任务
     * @param taskCompleteDTO 任务完成参数
     * @return 结果
     */
    @PostMapping("/completeDelegate")
    public AjaxResult completeDelegate(@RequestBody TaskCompleteDTO taskCompleteDTO){
        int rows = camundaService.completeDelegate(taskCompleteDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 取消委托
     * @param opinionDTO 任务ID、意见
     * @return 结果
     */
    @PostMapping("/cancelDelegate")
    public AjaxResult cancelDelegate(@RequestBody OpinionDTO opinionDTO){
        int rows = camundaService.cancelDelegate(opinionDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 转办
     * @param delegateDTO 任务ID、用户ID、意见
     * @return 结果
     */
    @PostMapping("/relayComplete")
    public AjaxResult relayComplete(@RequestBody DelegateDTO delegateDTO) {
        int rows = camundaService.relayComplete(delegateDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 退回到上一步的任务
     * @param opinionDTO 任务ID、意见
     * @return 结果
     */
    @PostMapping("/returnBackTask")
    public AjaxResult returnBackTask(@RequestBody OpinionDTO opinionDTO){
        int rows = camundaService.returnBackTask(opinionDTO);
        return rows > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 设计模板页面，获取选人列表
     * @param choseDTO 已选中的用户
     * @return 结果
     */
    @PostMapping("/getChoseUser")
    public AjaxResult getChoseUser(@RequestBody ChoseDTO choseDTO){
        try{
            SelectCompleteUserVO selectUserVOList = camundaService.getChoseUser(choseDTO);
            return AjaxResult.success(selectUserVOList);
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 设计模板页面，获取权限列表
     * @param choseDTO 已选中权限
     * @return 结果
     */
    @PostMapping("/getChoseAuth")
    public AjaxResult getChoseAuth(@RequestBody ChoseDTO choseDTO){
        try{
            AuthChoseVO authChoseVO = camundaService.getChoseAuth(choseDTO);
            return AjaxResult.success(authChoseVO);
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 设计模板页面，获取表达式列表
     * @return 结果
     */
    @PostMapping("/getChoseCondition")
    public AjaxResult getChoseCondition(){
        try{
            List<ConditionChoseVO> conditions = camundaService.getChoseCondition();
            return AjaxResult.success(conditions);
        } catch (RuntimeException e){
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 设计模板页面，根据表单标识获取表单中的变量
     * @param formList 表单标识集合
     * @return 结果
     */
    @PostMapping("/getFormVariable")
    public AjaxResult getFormVariable(@RequestBody List<String> formList) {
        List<CamundaFormEntity.Components> components = camundaService.getFormVariable(formList);
        return AjaxResult.success(components);
    }

    /**
     * 根据当前用户获取流程实例列表
     * @param page 分页与检索
     * @return 结果
     */
    @PostMapping("/getProcessInstanceByUser")
    public AjaxResult getProcessInstanceByUser(@RequestBody PageEntity<ProcessControlKeyDTO> page){
        TableDataInfo tableDataInfo = camundaService.getUserTask(page);
        return AjaxResult.success(tableDataInfo);
    }

    /**
     * 根据当前用户获取用户任务列表
     * @param page 分页与检索
     * @return 结果
     */
    @PostMapping("/getUserTaskByUser")
    public AjaxResult getUserTaskByUser(@RequestBody PageEntity<ProcessControlKeyDTO> page){
        TableDataInfo tableDataInfo = camundaService.getUserTaskByUser(page);
        return AjaxResult.success(tableDataInfo);
    }

    /**
     * 根据当前用户获取发出委托的用户任务列表
     * @param page 分页与检索
     * @return 结果
     */
    @PostMapping("/getDelegateTaskByUser")
    public AjaxResult getDelegateTaskByUser(@RequestBody PageEntity<ProcessControlKeyDTO> page){
        TableDataInfo tableDataInfo = camundaService.getDelegateTaskByUser(page);
        return AjaxResult.success(tableDataInfo);
    }

    /**
     * 根据当前用户获取具有的流程
     * @return 结果
     */
    @GetMapping("/getProcessByUserId")
    public AjaxResult getProcessByUserId(){
        List<ProcessByUserIdVO> process = camundaService.getProcessByUserId();
        return AjaxResult.success(process);
    }

    /**
     * 获取流程的开始表单
     * @param processVersionDTO 流程Key与版本
     * @return 结果
     */
    @PostMapping("/getProcessStartForm")
    public AjaxResult getProcessStartForm(@RequestBody ProcessVersionDTO processVersionDTO) {
        String startForm = camundaService.getProcessStartForm(processVersionDTO);
        return AjaxResult.success("", startForm);
    }

    /**
     * 根据流程Key和版本号获取流程模型
     * @param processVersionDTO 流程Key与版本号
     * @return 结果
     */
    @PostMapping("/getProcessBpmnByVersion")
    public AjaxResult getProcessBpmnByVersion(@RequestBody ProcessVersionDTO processVersionDTO) {
        String bpmn = camundaService.getProcessBpmnByVersion(processVersionDTO);
        return AjaxResult.success("", bpmn);
    }

    /**
     * 根据流程Key和版本号开启流程
     * @param startProcessVersionDTO 流程Key与版本
     * @return 结果
     */
    @PostMapping("/startProcessByVersion")
    public AjaxResult startProcessByVersion(@RequestBody StartProcessVersionDTO startProcessVersionDTO) {
        ProcessInstanceTitleVO processInstanceTitleVO = camundaService.startProcessByVersion(startProcessVersionDTO);
        return AjaxResult.success(processInstanceTitleVO);
    }

    /**
     * 获取流程的第一个节点的选人列表
     * @param startProcessVersionDTO 流程Key与版本
     * @return 结果
     */
    @PostMapping("/getStartProcessUserList")
    public AjaxResult getStartProcessUserList(@RequestBody StartProcessVersionDTO startProcessVersionDTO) {
        List<SelectUserVO> selectUserVOList = camundaService.getStartProcessUserList(startProcessVersionDTO);
        return AjaxResult.success(selectUserVOList);
    }

    /**
     * 获取流程定义的变量
     * @param processInstanceId 流程定义ID
     * @return 结果
     */
    @GetMapping("/getProcessVariable/{processInstanceId}")
    public AjaxResult getProcessVariable(@PathVariable String processInstanceId) {
        List<ProcessVariableVO> processVariableVO = camundaService.getProcessVariable(processInstanceId);
        return AjaxResult.success(processVariableVO);
    }

    /**
     * 获取流程审批日志流程
     * @param processInstanceId 流程定义ID
     * @return 结果
     */
    @GetMapping("/getProcessCommentLog/{processInstanceId}")
    public AjaxResult getProcessCommentLog(@PathVariable String processInstanceId) {
        ProcessCommentLogVO processCommentLog = camundaService.getProcessCommentLog(processInstanceId);
        return AjaxResult.success(processCommentLog);
    }

    /**
     * 获取流程流转步骤
     * @param processInstanceId 流程定义ID
     * @return 结果
     */
    @GetMapping("/getProcessNodeLog/{processInstanceId}")
    public AjaxResult getProcessNodeLog(@PathVariable String processInstanceId) {
        List<ProcessNodeLogVO> processNodeLogVOS = camundaService.getProcessNodeLog(processInstanceId);
        return AjaxResult.success(processNodeLogVOS);
    }

}
